package com.net.server.netty;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ChildChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.WriteCompletionEvent;
import org.jboss.netty.handler.timeout.IdleState;
import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
import org.jboss.netty.handler.timeout.IdleStateEvent;

import com.net.utils.PrintUtil;
import com.utils.UTF8;

/**
 * 
 * @author yangqifan
 *
 */
public class SessionHandler extends IdleStateAwareChannelHandler {
	// /**
	// * 常规的业务逻辑返回
	// */
	// protected static final byte STATE_COMMON = 0x00;
	// /**
	// * 登录成功
	// */
	// protected static final byte STATE_SUCC = 0x01;
	// /**
	// * 登录失败
	// */
	// protected static final byte STATE_FAIL = 0x02;
	// /**
	// * 链接已满
	// */
	// protected static final byte STATE_CONNECT_MAX = 0x03;
	// /**
	// * 系统错误
	// */
	// protected static final byte STATE_SYSTEM_ERROR = 0x04;
	// /**
	// * 系统维护中
	// */
	// protected static final byte STATE_MAINTENANCE = 0x05;
	// // private Logger logger =
	// Logger.getLogger(SessionHandler.class.getName());

	/**
	 * 验证是否超过最大连接数
	 */

	protected boolean checkMaxSession(ChannelHandlerContext session) {
		// int curSessions =
		// ChannelManage.getInstance().getChannelKeySet().size();
		// if (Constants.MAX_CONNECTIONS <= curSessions) {
		// return true;
		// }
		return false;
	}

	/**
	 * 调试覆盖的 write 后 super.handleUpstream
	 */
	@Override
	public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
		if (e instanceof IdleStateEvent)
			channelIdle(ctx, (IdleStateEvent) e);
		else {
			super.handleUpstream(ctx, e);
		}
	}

	// Invoked when a Channel is open, bound to a local address, and connected
	// to a remote address.
	@Override
	public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
		//PrintUtil.info("连接创建:" + e.getChannel().getRemoteAddress() + "====>>>>" + e.getChannel().getLocalAddress());
	}

	@Override
	public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
		PrintUtil.info("断开连接:" + e.getChannel().getRemoteAddress() + "====>>>>" + e.getChannel().getLocalAddress());
		//ChannelAttachment sessionAtta = (ChannelAttachment) ctx.getAttachment();
		//if (sessionAtta != null) {
		//	String uid = sessionAtta.getString(SessionAttributes.SESSION_ATTRIBUTE_NAME);
		//	Object object = sessionAtta.getObject(SessionAttributes.SESSION_ATTRIBUTE_LISTENER);
			//if (object instanceof ClientSessionListener) {
				//ClientSessionListener clientSessionListener = (ClientSessionListener) object;
				//clientSessionListener.disconnected(ctx.getChannel().getId());
			//}
			//LogicFactory.getOnlineUserLogic().removeUser(uid);
		//}
		//ChannelManage.getInstance().remove(ctx.getChannel().getId());
		super.channelDisconnected(ctx, e);
	}

	/**
	 * 异常不做关闭通道的操作，只做异常处理,这里如果抛出IO异常，框架会自动关闭连接
	 */
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
		e.getCause().printStackTrace();

		final Writer result = new StringWriter();
		final PrintWriter printWriter = new PrintWriter(result);
		e.getCause().printStackTrace(printWriter);

		if (ctx.getChannel().isConnected()) {
			// 返回异常提示
			//ctx.getChannel().write(SystemProtocol.Exception.respParams());
		}
	}

	@Override
	public void childChannelClosed(ChannelHandlerContext ctx, ChildChannelStateEvent e) throws Exception {
		PrintUtil.info("SessionHandler childChannelClosed channelIdle .... Time = ");
		super.childChannelClosed(ctx, e);
	}

	@Override
	public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
		PrintUtil.info("SessionHandler channelClosed ChannelStateEvent = " + e);
		super.channelClosed(ctx, e);
		ctx.sendUpstream(e);
	}

	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
		//PrintUtil.info("连接收到消息" + e.getMessage() + "|");
		ChannelBuffer message = (ChannelBuffer) e.getMessage();
		PrintUtil.info(new String(message.array(), UTF8.get()));
		System.out.println();
	}

	

	

	
	/**
	 * modify by ron 4:38:56 PM 检查是否登录成功，如果登录成功则
	 * 
	 * @param ctx
	 * @param name
	 * @param platform
	 * @return
	 * 
	 */

	@Override
	public void writeComplete(ChannelHandlerContext ctx, WriteCompletionEvent e) throws Exception {
//		// TODO 打印到log4j
//		// LoggerManager.Netty.debug(ctx.getChannel().getAttachment());
//		ChannelAttachment sessionAtta = (ChannelAttachment) ctx.getAttachment();
//		String uid = "";
//		if (sessionAtta != null) {
//			uid = sessionAtta.getString(SessionAttributes.SESSION_ATTRIBUTE_NAME);
//		}
//		LoggerManager.track.debug("WriteComplete|" + uid);
//		super.writeComplete(ctx, e);
	}


	/**
	 * 当一个Channel短暂空闲时被调用.
	 */
	@Override
	public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) throws Exception {
		PrintUtil.info("SessionHandler 超过设定时间 没发数据/心跳 来 channelIdle .... Time = ");
		if (e.getState() == IdleState.ALL_IDLE) {
			ctx.getChannel().close();// 关闭连接通道后，框架回调用channelDisconnected方法
		}
	}

}
